<?php
/**
 * 考勤签到模型
 */
class attendanceModel extends RelationModel {
    

    //发起关联，给后台使用，前台API 不需要使用这个
    protected $_link = array(
        'user' => array(
            'mapping_type' => BELONGS_TO,
            'class_name' => 'admin',
            'foreign_key' => 'userId',
            'as_fields'=>'storeId,userName,realName',
        ),
        'store' => array(
            'mapping_type' => BELONGS_TO,
            'class_name' => 'store',
            'foreign_key' => 'storeId',
            'as_fields'=>'name:storeName',
        ),        
    ); 

	/**
	 * 获得指定用户的签到记录
	 * @param int $userId
	 * @param string $month 月份
	 * @return array
	 */
	public function getCheckHistory($userId,$month){
		//计算要查看的考勤开始日期和结束日期
		import("ORG.Date");
		$Date = new Date($month);
		$endTime = strtotime($Date->lastDayOfMonth()) > time() ? strtotime(date('Y-m-d')) : strtotime($Date->lastDayOfMonth());
		$days = $Date->dateDiff($endTime);
	
		$list = array();
		$week = array('Sun'=>"日",'Mon'=>'一','Tue'=>'二','Wed'=>'三','Thu'=>'四','Fri'=>'五','Sat'=>'六');
		$verifyType = C('CHECK_VERIFY_TYPE');	//审核类型
		$user = D('admin')->where(array('id'=>$userId))->find();
		for ($index = 0 ; $index <= $days; $index++) {
			$workTime = $endTime - ($index * 86400);
	
			$attend = D('attendance')->where(array('workDate'=>date('Y-m-d', $workTime), 'userId'=>$userId))->find();
			
			$list[$index]['date'] = date('Y年m月d日', $workTime).' 星期'.$week[date('D', $workTime)];
			
			if($attend){
				$list[$index]['checkId']		= $attend['id'];
				$list[$index]['verifyTypeName']	= isset($verifyType[$attend['verifyType']]) ? $verifyType[$attend['verifyType']] : '未审核';
				$list[$index]['inWorkTime']		= $attend['inWorkTime'];
				$list[$index]['inWorkImage']	= $this->getCheckImageUrl($attend['inWorkImage']);
				$list[$index]['inWorkGPS']		= $attend['inWorkGPS'];
				$list[$index]['offWorkTime']	= $attend['offWorkTime'];
				$list[$index]['offWorkImage']	= $this->getCheckImageUrl($attend['offWorkImage']);
				$list[$index]['offWorkGPS']		= $attend['offWorkGPS'];
			}else{
				//如果找不到指定的打卡记录，则自动生成一条
				$attend['workDate']	= date('Y-m-d', $workTime);
				$attend['userId']	= $user['id'];
				$attend['storeId']	= $user['storeId'];
				
				$list[$index]['checkId'] = D('attendance')->add($attend);
				$list[$index]['verifyTypeName']	= '未审核';
				$list[$index]['inWorkTime']		= NULL;
				$list[$index]['inWorkImage']	= NULL;
				$list[$index]['inWorkGPS']		= NULL;
				$list[$index]['offWorkTime']	= NULL;
				$list[$index]['offWorkImage']	= NULL;
				$list[$index]['offWorkGPS']		= NULL;
			}
		}
		rsort($list);
		return $list;
	}
	
	/**
	 * 获得考勤审核主列表
	 * @param string $ids 用户id
	 * @return array
	 */
	public function getVerifyList($ids){
		import("@ORG.Date");
		$list = array('total'=>0);
		$userNum = count(explode(',', $ids));	//员工数
		$dateStart = date('Y-m-d', strtotime(date('Y-m', strtotime('last month')))) ;	//开始检查审核记录的那天（上个月的一号）
		$Date = new Date($dateStart);
		$dayNum	= $Date->dateDiff(date('Y-m-d'));	//计算开始那天与今天的天数差
		
		for ($index = 0 ; $index <= $dayNum; $index++) {
			$map['workDate']	= date('Y-m-d', strtotime("-{$index} days"));
			$map['userId']		= array('IN', $ids);
			$map['verifyType']	= array('neq', 0);
			
			//查询管辖的员工中，当天已经审核的条数
			$auditedCount = D('attendance')->where($map)->count();
			
			$list['total'] += $userNum - $auditedCount;
			$list['list'][] = array('date'=>$map['workDate'], 'num'=> $userNum - $auditedCount);
		}
		return $list;
	}
	
	/**
	 * 获得考勤审核子列表
	 * @param string $ids 用户id
	 * @param string $date 工作日期
	 * @return array
	 */
	public function getVerifySubList($ids, $date){
		$list = array();
		$users = D('admin')->field('id, realName, storeId')->where("id IN ({$ids})")->select();
		$verifyType = C('CHECK_VERIFY_TYPE');	//审核类型
		if($users){
			foreach ($users as $u){
				$list[$u['id']]['name'] = $u['realName'];
				
				$attend = D('attendance')->where(array('workDate'=>$date, 'userId'=>$u['id']))->find();
				if($attend){
					$list[$u['id']]['checkId'] = $attend['id'];
					$list[$u['id']]['verifyType'] = $attend['verifyType'];
					$list[$u['id']]['verifyTypeName'] = isset($verifyType[$attend['verifyType']]) ? "{$verifyType[$attend['verifyType']]}" : '未审核';
				}else{
					//如果些员工未有考勤数据，则自动生成一条
					$data['userId']			= $u['id'];
					$data['storeId']		= $u['storeId'];
					$data['workDate']		= $date;
					
					$list[$u['id']]['checkId'] = D('attendance')->add($data);
					$list[$u['id']]['verifyType'] = 0;
					$list[$u['id']]['verifyTypeName'] = '未审核';
				}
			}
		}
		return $list;
	}
	
	/**
	 * 获得考勤记录详情
	 * @param int $checkId
	 * @return  array
	 */
	public function getCheckDetail($checkId){
		//获得打卡记录信息
		$attend = D('attendance')->where(array('id'=>$checkId))->find();
		//获得请假记录信息
		$leave = D('leave')->where("userId={$attend['userId']} AND startTime <=".strtotime($attend['workDate'])." AND endTime >=".strtotime($attend['workDate']))->find();
		//请假类型
		$leaveType = C('LEAVE_TYPE'); 
		//获得用户个人信息
		$user = D('admin')->alias('user')->field('user.realName,store.name AS storeName')
				->join(C('DB_PREFIX')."store AS store ON user.storeId=store.id")
				->where("user.id = {$attend['userId']}")->find();
		$verifyType = C('CHECK_VERIFY_TYPE');	//审核类型
		
		$res['checkId']			= $checkId;
		$res['realName']		= $user['realName'];
		$res['storeName']		= $user['storeName'];
		$res['verifyType']		= $attend['verifyType'];
		$res['verifyTypeName']	= isset($verifyType[$attend['verifyType']]) ? $verifyType[$attend['verifyType']] : '未审核';
		$res['verifyRemark']	= $attend['verifyRemark'] ? $attend['verifyRemark'] : '';
		$res['checkInStatus']	= $attend['inWorkTime'] ? TRUE : FALSE;
		$res['checkInTime']		= $attend['inWorkTime'] ? date('Y-m-d H:i:s', $attend['inWorkTime']) : '';
		$res['checkInImage']	= $this->getCheckImageUrl($attend['inWorkImage']);
		$res['checkInGpsInfo']	= ""; //@TODO 上班打卡GPS定位校验结果
		$res['checkOffStatus']	= $attend['offWorkTime'] ? TRUE : FALSE;
		$res['checkOffTime']	= $attend['offWorkTime'] ? date('Y-m-d H:i:s', $attend['offWorkTime']) : '';
		$res['checkOffImage']	= $this->getCheckImageUrl($attend['offWorkImage']);
		$res['checkOffGpsInfo']	= ""; //@TODO 下班打卡GPS定位校验结果
		$res['leaveInfo']		= $leave ? $leaveType[$leave['type']] : '无请假信息';
		$res['leaveRemark']		= $leave ? $leave['remark'] : '';

		return $res;
	}
	
	/**
	 * 考勤审核选项
	 * 
	 * @return  array
	 */
	public function getVerifyOptions(){
		$verifyType = C('CHECK_VERIFY_TYPE');	//审核类型
		$list = array();
		foreach($verifyType as $key=>$val){
			$list[$key]['typeId'] = $key;
			$list[$key]['typeName'] = $val;
		}
		return $list;
	}
	
	/**
	 * 获得打卡图片的 URL 地址
	 * 
	 */
	public function getCheckImageUrl($image){
		if($image){
			$filename = C('pin_attach_path').$image;
			if(file_exists($filename)){
				return __ROOT__.$filename;
			}
		}
	}
	
	/**
	 * 检查打卡的定位信息是否有误
	 * @param string $gps 位置
     * @param string $storeId 营业厅id
	 */
	public function checkGpsInfo($gps, $storeId){
		if(empty($gps)){
			return '无定位信息';
		}
		$store = D('store')->where(array('id'=>$storeId))->find();
		if(empty($store['gps'])){
			return '营业厅无坐标信息';
		}
		$distance = $this->distance($gps, $store['gps']);
		
		//定位误差不超200米
		if($distance > 200){
			return '不在指定范围';
		}else{
			return '正常';
		}
	}
	
	/**
     * 获取两经纬度之间的距离
     * @param string $location1 位置1
     * @param string $location2 位置2
     * @param string $unit 距离单位
     */
    public function distance($location1, $location2, $unit = 'M') {
        //赋值
        $location1 = explode(',', $location1);
        $location2 = explode(',', $location2);
        $lon1 = $location1[0];
        $lat1 = $location1[1];
        $lon2 = $location2[0];
        $lat2 = $location2[1];

        $theta = $lon1 - $lon2;  

        $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));  
        $dist = acos($dist);  
        $dist = rad2deg($dist);  
        $miles = $dist * 60 * 1.1515;  
        $unit = strtoupper($unit);    
        if ($unit == "M") {  
            $dis = ($miles * 1609.344);  
        }elseif ($unit == "K") {  
            $dis = ($miles * 1.609344);  
        }elseif($unit == "N") {  
            $dis = ($miles * 0.8684);  
        }else{  
            $dis =  $miles;  
        } 
        return ceil($dis);  
    }
}

/* End of file attendanceModel.class.php */